package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var (
	name      string
	printName bool
	people    People
)

type People struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

// implement flag.Value
func (peo *People) String() string {
	bytes, err := json.Marshal(peo)
	if nil != err {
		panic(err)
	}
	return string(bytes)
}

// implement flag.Value
func (peo *People) Set(value string) error {
	list := strings.Split(value, ",")
	if len(list) > 0 {
		for i := range list {
			entry := list[i]
			if "name" == strings.Split(entry, ":")[0] {
				peo.Name = strings.Split(entry, ":")[1]
			} else if "age" == strings.Split(entry, ":")[0] {
				age, err := strconv.ParseInt(strings.Split(entry, ":")[1],
					10, 0)
				if nil != err {
					return err
				}
				peo.Age = int(age)
			}
		}
	}
	return nil
}

func newPeoPleValue(val People, p *People) *People {
	*p = val
	return (*People)(p)
}

func init() {
	flag.CommandLine = flag.NewFlagSet("", flag.ExitOnError)

	flag.CommandLine.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage of %s:\n", "PPPP")
		flag.PrintDefaults()
	}

	flag.CommandLine.Var(newPeoPleValue(People{Name: "Maggie", Age: 20}, &people),
		"p", "")

	flag.StringVar(&name, "name", "leon", "Input the name")
	flag.BoolVar(&printName, "pname", false, "If print name")
}

func main() {

	flag.Parse()

	fmt.Printf("People: %+v \n", people)

	fmt.Println("===================")
	if printName {
		fmt.Printf("name is %v \n", name)
	}
}
